﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Service.Etka.Models;

namespace Wicture.EPC.Service.Etka.Resources
{
    public static class ResourceHelper
    {
        private static string[] supprotedBrands = new string[] { "audi", "vw", "skoda", "seat", "porsche" };
        private static Lazy<Dictionary<string, Dictionary<string, string>>> etkaTextDict = new Lazy<Dictionary<string, Dictionary<string, string>>>(LoadTextDict);
        private static Lazy<Dictionary<string, HashSet<string>>> etkaEngineCodeDict = new Lazy<Dictionary<string, HashSet<string>>>(LoadEngineCodes);
        private static Lazy<Dictionary<string, HashSet<string>>> etkaTransmissionCodeDict = new Lazy<Dictionary<string, HashSet<string>>>(LoadTransmissionCodes);
        private static Lazy<Dictionary<string, Dictionary<string, List<PR>>>> etkaPRsDict = new Lazy<Dictionary<string, Dictionary<string, List<PR>>>>(LoadPRs);
        private static Lazy<Dictionary<string, HashSet<string>>> etkaShortEngineCodeDict = new Lazy<Dictionary<string, HashSet<string>>>(LoadShortEngineCodes);

        public static Dictionary<string, HashSet<string>> EtkaEngineCodeDict { get { return etkaEngineCodeDict.Value; } }
        public static Dictionary<string, HashSet<string>> EtkaShortEngineCodeDict { get { return etkaShortEngineCodeDict.Value; } }
        public static Dictionary<string, HashSet<string>> EtkaTransmissionCodeDict { get { return etkaTransmissionCodeDict.Value; } }

        public static Dictionary<string, Dictionary<string, List<PR>>> EtkaPRsDict { get { return etkaPRsDict.Value; } }
        private static Dictionary<string, HashSet<string>> LoadShortEngineCodes()
        {
            var result = new Dictionary<string, HashSet<string>>();

           foreach(var key in EtkaEngineCodeDict.Keys)
            {
                result.Add(key, EtkaEngineCodeDict[key].Select(q => q.Length > 3 ? q.Substring(0, 3) : q).ToHashSet());
            }
            return result;
        }

        private static Dictionary<string, HashSet<string>> LoadEngineCodes()
        {
            var result = new Dictionary<string, HashSet<string>>();

            var repository = new DbRESTFulRepository();
            foreach (var brandCode in supprotedBrands)
            {
                    repository.ConnectionManager?.ProcessGateway(null, JObject.FromObject(new { brandCode }), null);
                    IEnumerable<dynamic> data = repository.Invoke(CSIs.List_engine_code, null);
                    result[brandCode] = new HashSet<string>(data.Select(i => (string)i.engineCode));
            }

            return result;
        }

        private static Dictionary<string, HashSet<string>> LoadTransmissionCodes()
        {
            var result = new Dictionary<string, HashSet<string>>();

            var repository = new DbRESTFulRepository();
            foreach (var brandCode in supprotedBrands)
            {
                repository.ConnectionManager?.ProcessGateway(null, JObject.FromObject(new { brandCode }), null);
                IEnumerable<dynamic> data = repository.Invoke(CSIs.List_transmission_code, null);
                result[brandCode] = new HashSet<string>(data.Select(i => (string)i.transmissionCode));
            }

            return result;
        }

        private static Dictionary<string, Dictionary<string, List<PR>>> LoadPRs()
        {
            var result = new Dictionary<string, Dictionary<string,List<PR>>>();

            var repository = new DbRESTFulRepository();
            foreach (var brandCode in supprotedBrands)
            {
                repository.ConnectionManager?.ProcessGateway(null, JObject.FromObject(new { brandCode }), null);
                IEnumerable<PR> data = repository.Invoke<PR>(CSIs.List_pr_familie_nummer, null);
                result[brandCode] = data.GroupBy(q => q.PRNummer).ToDictionary(k => k.Key, v => v.ToList());
            }

            return result;
        }

        private static Dictionary<string, Dictionary<string, string>> LoadTextDict()
        {
            var result = new Dictionary<string, Dictionary<string, string>>();

            var repository = new DbRESTFulRepository();
            foreach (var brandCode in supprotedBrands)
            {
                repository.ConnectionManager?.ProcessGateway(null, JObject.FromObject(new { brandCode }), null);
                IEnumerable<dynamic> data = repository.Invoke(CSIs.List_text_dict, null);
                result[brandCode] = data.ToDictionary(k => (string)k.ts.ToString(), v => (string)v.text);
            }

            return result;
        }

        public static string Textify(string brandCode, IEnumerable<string> ids, string connector = "_", string appendingText = null)
        {
            if (ids == null || ids.Count() == 0) return null;

            var dict = etkaTextDict.Value[brandCode];

            var result = string.Join(connector, ids.Where(id => dict.ContainsKey(id)).Select(id => dict[id]));
            if (string.IsNullOrEmpty(appendingText)) return result;

            return result + connector + appendingText;
        }
    }
}
